"""
交易模式管理器

统一管理不同的交易模式：模拟盘、实盘、回测
提供统一的接口和配置管理
"""

from enum import Enum
from typing import Dict, Any, Optional, Union
from dataclasses import dataclass
import logging
from ..core.exceptions import ConfigError, ValidationError


class TradingMode(Enum):
    """交易模式枚举"""
    SIMULATION = "simulation"  # 模拟盘
    LIVE = "live"             # 实盘
    BACKTEST = "backtest"     # 回测


@dataclass
class TradingConfig:
    """交易配置"""
    mode: TradingMode
    exchange: str
    api_key: Optional[str] = None
    api_secret: Optional[str] = None
    passphrase: Optional[str] = None
    sandbox: bool = False
    initial_balance: Optional[Dict[str, float]] = None
    risk_limits: Optional[Dict[str, Any]] = None
    
    def __post_init__(self):
        """配置验证"""
        if self.mode == TradingMode.LIVE:
            if not all([self.api_key, self.api_secret]):
                raise ValidationError("实盘模式需要提供API密钥")
        
        if self.mode == TradingMode.SIMULATION:
            if not self.initial_balance:
                self.initial_balance = {'USDT': 10000.0}  # 默认1万USDT


class TradingModeManager:
    """交易模式管理器"""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.current_mode = None
        self.config = None
        self._exchange_adapter = None
        self._account_manager = None
        self._order_manager = None
        self._data_manager = None
    
    def set_mode(self, config: TradingConfig) -> bool:
        """设置交易模式"""
        try:
            self.config = config
            self.current_mode = config.mode
            
            # 根据模式初始化相应的组件
            if config.mode == TradingMode.SIMULATION:
                return self._setup_simulation_mode()
            elif config.mode == TradingMode.LIVE:
                return self._setup_live_mode()
            elif config.mode == TradingMode.BACKTEST:
                return self._setup_backtest_mode()
            else:
                raise ValidationError(f"不支持的交易模式: {config.mode}")
                
        except Exception as e:
            self.logger.error(f"设置交易模式失败: {e}")
            return False
    
    def _setup_simulation_mode(self) -> bool:
        """设置模拟盘模式"""
        try:
            from ..backtesting.mock_exchange import MockExchange
            from ..backtesting.mock_managers import MockAccountManager, MockOrderManager
            from ..backtesting.mock_data_manager import MockDataManager
            
            # 创建模拟交易所
            self._exchange_adapter = MockExchange(self.config.initial_balance)
            
            # 创建模拟管理器
            self._account_manager = MockAccountManager()
            self._order_manager = MockOrderManager()
            self._data_manager = MockDataManager({})
            
            self.logger.info(f"模拟盘模式设置完成，初始资金: {self.config.initial_balance}")
            return True
            
        except Exception as e:
            self.logger.error(f"设置模拟盘模式失败: {e}")
            return False
    
    def _setup_live_mode(self) -> bool:
        """设置实盘模式"""
        try:
            # 根据交易所类型创建适配器
            if self.config.exchange.lower() == 'okx':
                from ..exchanges.okx_exchange import OKXExchange
                self._exchange_adapter = OKXExchange({
                    'api_key': self.config.api_key,
                    'secret_key': self.config.api_secret,  # 修正参数名
                    'passphrase': self.config.passphrase,
                    'sandbox': self.config.sandbox
                })
            elif self.config.exchange.lower() == 'binance':
                from ..exchanges.binance_exchange import BinanceExchange
                self._exchange_adapter = BinanceExchange({
                    'api_key': self.config.api_key,
                    'secret_key': self.config.api_secret,  # 修正参数名
                    'sandbox': self.config.sandbox
                })
            else:
                raise ValidationError(f"不支持的交易所: {self.config.exchange}")
            
            # 创建实盘管理器
            from ..trading.account_manager import AccountManager
            from ..trading.order_manager import OrderManager
            from ..data.data_manager import DataManager
            
            self._account_manager = AccountManager('./storage')  # 修正参数
            self._order_manager = OrderManager('./storage')     # 修正参数
            self._data_manager = DataManager({})
            
            # 测试连接
            if not self._exchange_adapter.connect():
                raise ConnectionError("无法连接到交易所")
            
            self.logger.info(f"实盘模式设置完成，交易所: {self.config.exchange}")
            return True
            
        except Exception as e:
            self.logger.error(f"设置实盘模式失败: {e}")
            return False
    
    def _setup_backtest_mode(self) -> bool:
        """设置回测模式"""
        try:
            from ..backtesting.backtest_engine import BacktestEngine
            from ..backtesting.mock_exchange import MockExchange
            from ..backtesting.mock_managers import MockAccountManager, MockOrderManager
            from ..backtesting.mock_data_manager import MockDataManager
            
            # 创建回测交易所
            self._exchange_adapter = MockExchange(self.config.initial_balance)
            
            # 创建回测管理器 - MockOrderManager不需要参数
            self._account_manager = MockAccountManager()
            self._order_manager = MockOrderManager()
            
            # 回测使用模拟数据管理器
            self._data_manager = MockDataManager({})
            
            self.logger.info("回测模式设置完成")
            return True
            
        except Exception as e:
            self.logger.error(f"设置回测模式失败: {e}")
            return False
    
    def get_exchange_adapter(self):
        """获取交易所适配器"""
        return self._exchange_adapter
    
    def get_account_manager(self):
        """获取账户管理器"""
        return self._account_manager
    
    def get_order_manager(self):
        """获取订单管理器"""
        return self._order_manager
    
    def get_data_manager(self):
        """获取数据管理器"""
        return self._data_manager
    
    def is_simulation(self) -> bool:
        """是否为模拟模式"""
        return self.current_mode == TradingMode.SIMULATION
    
    def is_live(self) -> bool:
        """是否为实盘模式"""
        return self.current_mode == TradingMode.LIVE
    
    def is_backtest(self) -> bool:
        """是否为回测模式"""
        return self.current_mode == TradingMode.BACKTEST
    
    def get_mode_info(self) -> Dict[str, Any]:
        """获取模式信息"""
        if not self.config:
            return {}
        
        return {
            'mode': self.current_mode.value if self.current_mode else None,
            'exchange': self.config.exchange,
            'sandbox': self.config.sandbox,
            'has_api_keys': bool(self.config.api_key and self.config.api_secret),
            'initial_balance': self.config.initial_balance,
            'risk_limits': self.config.risk_limits
        }
    
    def validate_strategy_config(self, strategy_config: Dict[str, Any]) -> bool:
        """验证策略配置是否适合当前模式"""
        try:
            if not self.current_mode:
                raise ValidationError("未设置交易模式")
            
            # 检查交易所匹配
            strategy_exchange = strategy_config.get('exchange', '').lower()
            if strategy_exchange and strategy_exchange != self.config.exchange.lower():
                self.logger.warning(f"策略交易所 {strategy_exchange} 与当前模式交易所 {self.config.exchange} 不匹配")
            
            # 模拟盘特殊检查
            if self.current_mode == TradingMode.SIMULATION:
                # 检查初始资金是否足够
                required_balance = strategy_config.get('required_balance', {})
                if required_balance:
                    for currency, amount in required_balance.items():
                        available = self.config.initial_balance.get(currency, 0)
                        if available < amount:
                            raise ValidationError(f"模拟盘{currency}余额不足: 需要{amount}, 可用{available}")
            
            # 实盘特殊检查
            elif self.current_mode == TradingMode.LIVE:
                # 检查风险限制
                if self.config.risk_limits:
                    max_position = self.config.risk_limits.get('max_position_ratio', 1.0)
                    strategy_position = strategy_config.get('max_position_ratio', 0.8)
                    if strategy_position > max_position:
                        raise ValidationError(f"策略仓位比例 {strategy_position} 超过风险限制 {max_position}")
            
            return True
            
        except Exception as e:
            self.logger.error(f"验证策略配置失败: {e}")
            return False
    
    def get_risk_limits(self) -> Dict[str, Any]:
        """获取风险限制"""
        if not self.config or not self.config.risk_limits:
            # 默认风险限制
            return {
                'max_position_ratio': 0.8,      # 最大仓位比例
                'max_drawdown': 0.1,            # 最大回撤
                'daily_loss_limit': 0.05,       # 日损失限制
                'max_orders_per_minute': 10,    # 每分钟最大订单数
                'min_order_amount': 10.0        # 最小订单金额
            }
        
        return self.config.risk_limits.copy()
    
    def shutdown(self) -> None:
        """关闭交易模式管理器"""
        try:
            if self._exchange_adapter and hasattr(self._exchange_adapter, 'close'):
                self._exchange_adapter.close()
            
            self.current_mode = None
            self.config = None
            self._exchange_adapter = None
            self._account_manager = None
            self._order_manager = None
            self._data_manager = None
            
            self.logger.info("交易模式管理器已关闭")
            
        except Exception as e:
            self.logger.error(f"关闭交易模式管理器失败: {e}")


# 全局交易模式管理器实例
trading_mode_manager = TradingModeManager()


def get_trading_mode_manager() -> TradingModeManager:
    """获取全局交易模式管理器"""
    return trading_mode_manager


def create_trading_config(mode: str, **kwargs) -> TradingConfig:
    """创建交易配置的便捷函数"""
    mode_enum = TradingMode(mode.lower())
    return TradingConfig(mode=mode_enum, **kwargs)